import { useContext, useEffect } from "react";
import { useHistory } from "react-router-dom";
import { ToastContext } from "@humansignal/ui";

export const DRAFT_GUARD_KEY = "DRAFT_GUARD";

export const draftGuardCallback = {
  current: null,
};

export const DraftGuard = () => {
  const toast = useContext(ToastContext);
  const history = useHistory();

  useEffect(() => {
    const unblock = () => {
      draftGuardCallback.current?.(true);
      draftGuardCallback.current = null;
    };

    /**
     * The version of Router History that is in use does not currently support
     * the `block` method fully. This is a workaround to allow us to block navigation
     * when there are unsaved changes. The draftGuardCallback allows the unblock callback to be captured from the
     * history callback `getUserConfirmation` that is triggered by returning a string message from history.block, allowing the user to
     * confirm they want to leave the page. Here we send through a constant message
     * to signify that we aren't looking for user confirmation but to utilize this to enable navigation blocking based on
     * unsuccessful draft saves.
     */
    const unsubscribe = history.block(() => {
      const selected = window.Htx?.annotationStore?.selected;
      const submissionInProgress = !!selected?.submissionStarted;
      const hasChanges = !!selected?.history.undoIdx && !submissionInProgress;

      if (hasChanges) {
        selected.saveDraftImmediatelyWithResults()?.then((res) => {
          const status = res?.$meta?.status;

          if (status === 200 || status === 201) {
            toast.show({ message: "Draft saved successfully", type: "info" });
            unblock();
          } else if (status !== undefined) {
            toast.show({ message: "There was an error saving your draft", type: "error" });
          } else {
            unblock();
          }
        });

        return DRAFT_GUARD_KEY;
      }
    });

    return () => {
      unblock();
      unsubscribe();
    };
  }, []);

  return <></>;
};
